<template>
  <div class="document-container">
    <!-- 顶部生成内容容器 -->
    <div class="content-container animate-fade-in">
      <template v-if="isGenerating">
        <div class="loading-container animate-pulse">
          <LoadingDots />
          <span class="loading-text">正在生成内容...</span>
        </div>
      </template>
      <div 
        v-else 
        class="generated-content" 
        v-html="generatedContent"
        :class="{ 'animate-fade-in-up': generatedContent }"
      ></div>
    </div>

    <!-- 功能提示区域（显眼位置） -->
    <div class="notice-bar animate-fade-in" style="animation-delay: 0.3s">
      <el-icon class="notice-icon"><InfoFilled /></el-icon>
      <span class="notice-text">
        目前只支持静态网页、pdf文档、docx文档、txt文档的读取摘要，后续会上线更多功能 | 读取时间较长（1-2分钟），请耐心等待生成完成
      </span>
    </div>

    <!-- 底部输入区域 -->
    <div class="input-section animate-fade-in" style="animation-delay: 0.2s">
      <!-- 文档选择区域 -->
      <div class="doc-select-area">
        <span class="label">文档选择</span>
        <div class="url-input-container">
          <input 
            type="text" 
            v-model="formData.url"
            placeholder="请输入或选择文档..."
            class="input-field"
          >
          <button 
            class="select-button btn-hover" 
            @click="openFileDialog"
          >
            选择
          </button>
        </div>
      </div>

      <!-- 四个输入框一行显示 -->
      <div class="input-row">
        <div class="input-item" v-for="(item, idx) in inputItems" :key="idx">
          <input 
            type="text" 
            v-model="formData[item.key]"
            :placeholder="item.placeholder"
            class="input-field"
          >
        </div>
      </div>

      <!-- 生成按钮 -->
      <div class="button-area">
        <button 
          class="start-button btn-hover" 
          @click="startGeneration"
          :disabled="isGenerating"
          :class="{ 'btn-loading': isGenerating }"
        >
          <span v-if="!isGenerating">开始生成</span>
          <LoadingDots size="16" v-else />
        </button>
      </div>
    </div>

    <!-- 文件夹选择弹窗 -->
    <el-dialog 
      v-model="fileDialogVisible" 
      title="选择文件" 
      width="50%"
      :enter-animation="dialogEnterAnim"
      :leave-animation="dialogLeaveAnim"
    >
      <div class="file-browser">
        <!-- 面包屑导航 -->
        <div class="breadcrumb" v-if="currentPath.length > 0">
          <span 
            v-for="(item, index) in currentPath" 
            :key="item.id"
            class="breadcrumb-item"
          >
            <span 
              class="breadcrumb-link" 
              @click="navigateTo(index)"
              :class="{ 'link-hover': true }"
            >{{ item.label }}</span>
            <span v-if="index < currentPath.length - 1" class="separator">/</span>
          </span>
        </div>

        <!-- 文件列表 -->
        <div class="file-list">
          <div 
            v-for="item in currentFiles" 
            :key="item.id"
            class="file-list-item"
            :class="{ 
              'is-folder': item.isDir === 1,
              'is-selected': selectedFile?.id === item.id,
              'item-hover': true
            }"
            @click="handleItemClick(item)"
            :style="{ animationDelay: `${index * 0.03}s` }"
          >
            <el-icon><Document v-if="item.isDir !== 1" /><Folder v-else /></el-icon>
            <span class="file-name">{{ item.fileName }}</span>
            <span class="file-info" v-if="item.isDir !== 1">
              {{ formatFileSize(item.fileSize) }} | {{ formatDate(item.updateTime) }}
            </span>
          </div>
        </div>
      </div>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="fileDialogVisible = false" class="btn-hover">取消</el-button>
          <el-button 
            type="primary" 
            @click="confirmSelection"
            :disabled="!selectedFile || selectedFile.isDir === 1"
            class="btn-hover"
          >确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { listFiles, downloadUrlParam } from '@/api/file'
import { useLoginUserStore } from '@/store/user'
import { Document, Folder, InfoFilled } from '@element-plus/icons-vue' // 新增InfoFilled图标
import LoadingDots from '@/components/common/LoadingDots.vue'
import { getApiUrl, API_PATHS } from '@/config/api'

const { loginUser } = useLoginUserStore()
const generatedContent = ref('')
const isGenerating = ref(false)
const fileDialogVisible = ref(false)
const selectedFile = ref<API.FileDTO | null>(null)
const currentPath = ref<API.TreeNodeDTO[]>([])
const currentFiles = ref<API.FileDTO[]>([])

// 输入项配置化
const inputItems = [
  { key: 'length', placeholder: '概要长度' },
  { key: 'language', placeholder: '输出语言' },
  { key: 'summary_type', placeholder: '生成风格' },
  { key: 'additional_instructions', placeholder: '附加内容' }
]

// 新增默认值：概要长度=适中，输出语言=中文
const formData = reactive({
  url: '',
  length: '适中', // 概要长度默认值
  language: '中文', // 输出语言默认值
  summary_type: '',
  additional_instructions: ''
})

// 弹窗动画配置
const dialogEnterAnim = {
  enterFrom: { opacity: 0, transform: 'translateY(-20px)' },
  enterActive: { opacity: 1, transform: 'translateY(0)', transition: { duration: 0.3 } }
}
const dialogLeaveAnim = {
  leaveActive: { opacity: 0, transform: 'translateY(-20px)', transition: { duration: 0.3 } }
}

// 处理文件或文件夹点击
const handleItemClick = async (item: API.FileDTO) => {
  if (item.isDir === 1) {
    try {
      const response = await listFiles({
        parent_id: item.id
      })
      if (response.data?.success && response.data.data) {
        currentFiles.value = response.data.data.map((file, idx) => ({ ...file, animDelay: idx * 0.03 }))
        currentPath.value.push({
          id: item.id,
          label: item.fileName
        } as API.TreeNodeDTO)
      }
    } catch (error) {
      console.error('获取文件列表失败:', error)
      ElMessage.error('获取文件列表失败')
    }
  } else {
    selectedFile.value = item
  }
}

// 导航到指定层级
const navigateTo = async (index: number) => {
  if (index >= currentPath.value.length - 1) return
  
  const targetFolder = currentPath.value[index]
  currentPath.value = currentPath.value.slice(0, index + 1)
  
  try {
    const response = await listFiles({
      parent_id: targetFolder.id
    })
    if (response.data?.success && response.data.data) {
      currentFiles.value = response.data.data.map((file, idx) => ({ ...file, animDelay: idx * 0.03 }))
    }
  } catch (error) {
    console.error('获取文件列表失败:', error)
    ElMessage.error('获取文件列表失败')
  }
}

// 打开文件选择弹窗
const openFileDialog = async () => {
  fileDialogVisible.value = true
  currentPath.value = []
  selectedFile.value = null
  
  try {
    const response = await listFiles({
      parent_id: 0
    })
    if (response.data?.success && response.data.data) {
      currentFiles.value = response.data.data.map((file, idx) => ({ ...file, animDelay: idx * 0.03 }))
    }
  } catch (error) {
    console.error('获取文件列表失败:', error)
    ElMessage.error('获取文件列表失败')
  }
}

// 确认选择
const confirmSelection = async () => {
  if (!selectedFile.value || selectedFile.value.isDir === 1) {
    ElMessage.warning('请选择一个文件')
    return
  }

  try {
    const response = await downloadUrlParam({
      fileIds: [String(selectedFile.value.id)]
    })

    if (response.data?.success && response.data.data) {
      const baseUrl = formData.url.trim()
      const downloadUrl = response.data.data[0].downloadUrl
      formData.url = baseUrl ? `${baseUrl}${downloadUrl}` : downloadUrl
      fileDialogVisible.value = false
      ElMessage.success('文件选择成功')
    } else {
      ElMessage.error('获取文件下载地址失败')
    }
  } catch (error) {
    console.error('获取文件下载地址失败:', error)
    ElMessage.error('获取文件下载地址失败')
  }
}

// 格式化文件大小
const formatFileSize = (size: number) => {
  if (!size) return '0 B'
  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  let index = 0
  let fileSize = size

  while (fileSize >= 1024 && index < units.length - 1) {
    fileSize /= 1024
    index++
  }

  return `${fileSize.toFixed(2)} ${units[index]}`
}

// 格式化日期
const formatDate = (timestamp: number) => {
  if (!timestamp) return '-'
  return new Date(timestamp).toLocaleString()
}

// 处理流式响应
const processStreamResponse = async (response: Response) => {
  const reader = response.body?.getReader()
  if (!reader) return

  generatedContent.value = ''
  const decoder = new TextDecoder()
  let buffer = '' // 用于存储不完整的行

  try {
    while (true) {
      const { done, value } = await reader.read()
      if (done) break

      // 解码当前数据块并添加到缓冲区
      buffer += decoder.decode(value, { stream: true })
      
      // 按行分割缓冲区
      const lines = buffer.split('\n')
      // 最后一行可能不完整，留到下次处理
      buffer = lines.pop() || ''
      
      for (const line of lines) {
        const trimmedLine = line.trim()
        if (!trimmedLine) continue
        
        // 处理SSE格式，移除"data:"前缀
        const dataStr = trimmedLine.startsWith('data:') 
          ? trimmedLine.slice(5).trim() 
          : trimmedLine
        
        // 检查是否是结束标记
        if (dataStr === '[DONE]') {
          break
        }
        
        try {
          // 解析JSON数据
          const jsonData = JSON.parse(dataStr)
          if (jsonData.code === 0 && jsonData.data) {
            // 拼接内容
            generatedContent.value += jsonData.data
          }
        } catch (e) {
          console.error('解析JSON错误:', e, '原始数据:', dataStr)
        }
      }
    }

    // 处理剩余的缓冲区内容
    if (buffer.trim()) {
      console.log('剩余未处理的数据:', buffer)
    }

    // 响应完成后清空输入框（保留默认值）
    formData.url = ''
    formData.summary_type = ''
    formData.additional_instructions = ''
    // 保留概要长度和输出语言的默认值，不清空
  } catch (error) {
    console.error('流式读取错误:', error)
    generatedContent.value += '\n[读取数据时发生错误]'
  } finally {
    isGenerating.value = false
  }
}

// 开始生成
const startGeneration = async () => {
  if (!formData.url) {
    ElMessage.warning('请选择文档')
    return
  }

  isGenerating.value = true
  // 生成前再次提示时间信息，强化用户认知
  ElMessage.info('文档正在解析中，预计1-2分钟，请耐心等待...')
  try {
    const response = await fetch(getApiUrl(API_PATHS.DOCUMENT), {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        url: formData.url,
        summary_type: formData.summary_type,
        language: formData.language,
        length: formData.length,
        additional_instructions: formData.additional_instructions
      })
    })

    if (!response.ok) {
      throw new Error(`请求失败: ${response.status} ${response.statusText}`)
    }

    await processStreamResponse(response)
  } catch (error) {
    console.error('请求错误:', error)
    generatedContent.value = '生成过程中发生错误，请稍后重试'
    isGenerating.value = false
  }
}
</script>

<style scoped>
/* 基础布局 */
.document-container { display: flex; flex-direction: column; height: 100vh; padding: 20px; gap: 20px; background: #f8fafc; }
.content-container { flex: 1; background: #fff; border-radius: 12px; padding: 24px; overflow-y: auto; min-height: 200px; box-shadow: 0 2px 10px rgba(0,0,0,0.03); }
.generated-content { white-space: pre-wrap; line-height: 1.7; color: #334155; }
.input-section { background: #fff; border-radius: 12px; padding: 24px; box-shadow: 0 2px 10px rgba(0,0,0,0.03); }

/* 新增：功能提示栏样式 */
.notice-bar { 
  display: flex; 
  align-items: center; 
  gap: 10px; 
  padding: 12px 20px; 
  background: #fffbeb; 
  border-left: 4px solid #faad14; 
  border-radius: 8px; 
  color: #fa8c16; 
  font-size: 14px; 
  box-shadow: 0 2px 8px rgba(250,173,20,0.1); 
}
.notice-icon { font-size: 18px; }
.notice-text { flex: 1; line-height: 1.5; }

/* 输入区域样式 */
.doc-select-area { margin-bottom: 24px; }
.label { display: inline-block; margin-bottom: 8px; font-weight: 500; color: #475569; }
.url-input-container { display: flex; gap: 10px; align-items: center; }
.input-row { display: flex; gap: 16px; margin-bottom: 24px; }
.input-item { flex: 1; }
.input-field { width: 90%; padding: 14px; border: 2px solid #e2e8f0; border-radius: 8px; font-size: 14px; background: #fff; transition: all 0.2s; }
.input-field:focus { outline: none; border-color: #1890ff; box-shadow: 0 0 0 3px rgba(24,144,255,0.1); }

/* 按钮样式 */
.button-area { display: flex; justify-content: center; }
.select-button { padding: 0 20px; height: 48px; background: #1890ff; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; transition: all 0.3s; }
.start-button { padding: 14px 48px; background: #1890ff; color: #fff; border: none; border-radius: 8px; font-size: 16px; font-weight: 500; cursor: pointer; transition: all 0.3s; display: flex; align-items: center; gap: 8px; }
.start-button:hover { background: #40a9ff; transform: translateY(-2px); }
.start-button:disabled { background: #f0f2f5; color: #c9cdd4; cursor: not-allowed; transform: none; }
.btn-loading { background: #f0f2f5; }
.btn-hover:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(24,144,255,0.2); }

/* 加载样式 */
.loading-container { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 150px; color: #94a3b8; }
.loading-text { margin-top: 12px; font-size: 14px; }

/* 滚动条样式 */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: #f1f5f9; border-radius: 3px; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

/* 弹窗文件浏览器样式 */
.file-browser { display: flex; flex-direction: column; gap: 16px; }
.breadcrumb { display: flex; align-items: center; flex-wrap: wrap; padding: 8px 12px; background: #f5f7fa; border-radius: 6px; }
.breadcrumb-item { display: flex; align-items: center; }
.breadcrumb-link { color: #409EFF; cursor: pointer; padding: 2px 4px; border-radius: 4px; transition: all 0.2s; }
.link-hover:hover { background: #ecf5ff; }
.separator { margin: 0 8px; color: #909399; }
.file-list { display: flex; flex-direction: column; gap: 4px; max-height: 400px; overflow-y: auto; padding-right: 8px; }
.file-list-item { display: flex; align-items: center; padding: 10px 12px; border-radius: 6px; cursor: pointer; transition: all 0.2s; animation: fadeIn 0.3s ease forwards; opacity: 0; }
.item-hover:hover { background: #f5f7fa; transform: translateX(4px); }
.file-list-item.is-selected { background: #ecf5ff; border-left: 3px solid #409EFF; }
.file-list-item .el-icon { margin-right: 12px; font-size: 18px; color: #909399; }
.file-name { flex: 1; margin-right: 16px; color: #303133; }
.file-info { color: #909399; font-size: 12px; white-space: nowrap; }
.file-list-item.is-folder { color: #409EFF; }
.file-list-item.is-folder .el-icon { color: #409EFF; }

/* 动画类 */
.animate-fade-in { animation: fadeIn 0.6s ease forwards; opacity: 0; }
.animate-fade-in-up { animation: fadeInUp 0.6s ease forwards; opacity: 0; transform: translateY(15px); }
.animate-pulse { animation: pulse 1.5s infinite; }

/* 动画关键帧 */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeInUp { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: translateY(0); } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } }

/* 响应式适配 - 平板 */
@media (max-width: 968px) {
  .document-container { padding: 16px; gap: 16px; }
  .content-container, .input-section { padding: 20px; }
  .notice-bar { padding: 10px 16px; font-size: 13px; }
  .input-row { gap: 12px; }
  .start-button { padding: 12px 40px; font-size: 15px; }
  .el-dialog { width: 70% !important; }
}

/* 响应式适配 - 手机横屏 */
@media (max-width: 768px) {
  .input-row { flex-direction: column; gap: 16px; }
  .generated-content { line-height: 1.6; }
  .content-container { padding: 16px; }
  .input-field { padding: 12px; }
  .notice-bar { flex-direction: column; align-items: flex-start; padding: 12px 16px; }
  .el-dialog { width: 85% !important; }
  .file-list { max-height: 300px; }
}

/* 响应式适配 - 手机竖屏 */
@media (max-width: 480px) {
  .document-container { padding: 12px; gap: 12px; }
  .input-section { padding: 16px; }
  .doc-select-area { margin-bottom: 20px; }
  .url-input-container { flex-direction: column; gap: 8px; }
  .url-input-container input { width: 100%; }
  .select-button { width: 100%; }
  .start-button { width: 100%; padding: 14px 0; }
  .loading-container { min-height: 120px; }
  .el-dialog { width: 95% !important; }
  .file-name { font-size: 13px; }
  .file-info { display: none; }
  .notice-text { font-size: 12px; }
}
</style>